#include "museum.h"
#include "definition.h"

Museum::Museum()
{
    elem_num = 0;
    elem = NULL;
    rule_num = 0;
    rule = NULL;
    zero_inDeg_elem_num = 0;
    zero_inDeg_elem = NULL;
}
Museum::~Museum()
{
    FREE(elem);
    FREE(rule);
    FREE(zero_inDeg_elem);
}
void Museum::load()
{
    std::ifstream elem_file("elem.csv");
    elem_file >> elem_num;
    FREE(elem);
    elem = new Elem[elem_num];
    for (int i = 0; i < elem_num; i++)
        elem[i].read(elem_file);
    elem_file.close();

    std::ifstream rule_file("rule.csv");
    rule_file >> rule_num;
    FREE(rule);
    rule = new Rule[rule_num];
    for (int i = 0; i < rule_num; i++)
    {
        rule[i].read(rule_file);
        elem[rule[i].product].inDeg++;
    }
    rule_file.close();
    FREE(zero_inDeg_elem);
    zero_inDeg_elem = new int[elem_num];
    for (int i = 0; i < elem_num; i++)
        if (elem[i].inDeg == 0)
            zero_inDeg_elem[zero_inDeg_elem_num++] = i;
}
void Museum::save()
{
    std::ofstream elem_file("elem.csv");
    std::ofstream rule_file("rule.csv");

    elem_file << elem_num << std::endl;
    rule_file << rule_num << std::endl;
    elem = new Elem[elem_num];
    rule = new Rule[rule_num];
    for (int i = 0; i < elem_num; i++)
        elem[i].write(elem_file);
    for (int i = 0; i < rule_num; i++)
        rule[i].write(rule_file);

    elem_file.close();
    rule_file.close();
}
int Museum::mix(const int elem1, const int elem2)
{
    for (int i = 0; i < rule_num; i++)
        if (rule[i].cmp(elem1, elem2))
            return rule[i].product;
    return -1;
}
// void Museum::addElem(const Elem &e)
// {
//     Elem *new_elem = new Elem[elem_num + 1];
//     for (int i = 0; i < elem_num; i++)
//         new_elem[i].set(elem[i]);
//     new_elem[elem_num].set(e);
//     elem_num++;
//     if (elem != NULL)
//         delete[] elem;
//     elem = new_elem;
// }
// void Museum::addRule(const Rule &r)
// {
//     Rule *new_rule = new Rule[rule_num + 1];
//     for (int i = 0; i < rule_num; i++)
//         new_rule[i] = rule[i];
//     new_rule[rule_num] = r;
//     rule_num++;
//     if (rule != NULL)
//         delete[] rule;
//     rule = new_rule;
// }
// void Museum::set(const Museum &museum)
// {
//     elem_num = museum.elem_num;
//     if (elem != NULL)
//         delete[] elem;
//     elem = new Elem[elem_num];
//     for (int i = 0; i < elem_num; i++)
//         elem[i].set(museum.elem[i]);

//     rule_num = museum.rule_num;
//     if (rule != NULL)
//         delete[] rule;
//     rule = new Rule[rule_num];
//     for (int i = 0; i < rule_num; i++)
//         rule[i] = museum.rule[i];
// }

Elem::Elem(int id_, const char* name_, bool gotten_)
{
    id = id_;
    int namelength = strlen(name_);
    if (namelength == 0)
        name = NULL;
    else
    {
        name = new char[namelength];
        strcpy(name, name_);
    }
    gotten = gotten_;
    inDeg = 0;
}
Elem::~Elem()
{
    if (name != NULL)
        delete[] name;
    name = NULL;
}
void Elem::set(const Elem& elem)
{
    id = elem.id;
    name = new char[strlen(elem.name)];
    strcpy(name, elem.name);
    gotten = elem.gotten;
}
void Elem::got()
{
    gotten = true;
}
void Elem::read(std::istream& input)
{
    input >> id;
    char str[32];
    input >> str;
    name = new char[strlen(str)];
    strcpy(name, str);
    input >> gotten;
}
void Elem::write(std::ostream& output)
{
    output << id << " " << name << " " << gotten << std::endl;
}
Rule::Rule(int e1, int e2, int p)
{
    elem1 = e1, elem2 = e2, product = p;
}
Rule::~Rule() {}
int Rule::cmp(const int e1, const int e2)
{
    return elem1 == e1 && elem2 == e2 || elem1 == e2 && elem2 == e1;
}
void Rule::read(std::istream& input)
{
    input >> elem1 >> elem2 >> product;
}
void Rule::write(std::ostream& output)
{
    output << elem1 << " " << elem2 << product << std::endl;
}